﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;

namespace Silverlight3dApp.Learning.Lesson04
{
    public abstract class Sprite
    {
        protected readonly Texture2D _Texture;

        protected Vector2 _Position;

        protected Vector2 _FrameSize;
        protected readonly int _CollisionOffset;

        protected Vector2 _CurrentFrame;
        protected Vector2 _SheetSize;

        protected Vector2 _Speed;

        protected readonly SoundEffect _CollisionSound;

        protected readonly int _MillisecondsPerFrame;
        protected int _TimeSinceLastFrame;

        protected Sprite(Texture2D texture, Vector2 position, Vector2 frameSize, int collisionOffset, Vector2 currentFrame, Vector2 sheetSize, Vector2 speed, SoundEffect collisionSound)
        {
            _Texture = texture;
            _Position = position;
            _FrameSize = frameSize;
            _CollisionOffset = collisionOffset;
            _CurrentFrame = currentFrame;
            _SheetSize = sheetSize;
            _Speed = speed;
            _CollisionSound = collisionSound;
            _MillisecondsPerFrame = 50;
        }

        protected Sprite(Texture2D texture, Vector2 position, Vector2 frameSize, int collisionOffset, Vector2 currentFrame, Vector2 sheetSize, Vector2 speed, SoundEffect collisionSound, int millisecondsPerFrame)
        {
            _Texture = texture;
            _Position = position;
            _FrameSize = frameSize;
            _CollisionOffset = collisionOffset;
            _CurrentFrame = currentFrame;
            _SheetSize = sheetSize;
            _Speed = speed;
            _CollisionSound = collisionSound;
            _MillisecondsPerFrame = millisecondsPerFrame;
        }

        public abstract Vector2 Direction
        {
            get;
        }

        public Vector2 Position
        {
            get
            {
                return _Position;
            }
        }

        public Rectangle CollisionRectangle
        {
            get
            {
                return new Rectangle((int) _Position.X + _CollisionOffset, (int) _Position.Y + _CollisionOffset, (int) _FrameSize.X - (_CollisionOffset * 2), (int) _FrameSize.Y - (_CollisionOffset * 2));
            }
        }

        public void PlayCollisionSound()
        {
            if (_CollisionSound != null)
            {
                _CollisionSound.Play();
            }
        }
        
        public bool IsOutOfBounds(Rectangle rectangle)
        {
            return _Position.X < -_FrameSize.X || _Position.X > rectangle.Width || _Position.Y < -_FrameSize.Y || _Position.Y > rectangle.Height;
        }

        public virtual void Update(GameTime gameTime, Rectangle clientBounds)
        {
            _TimeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;
            if (_TimeSinceLastFrame > _MillisecondsPerFrame)
            {
                _TimeSinceLastFrame -= _MillisecondsPerFrame;
                ++_CurrentFrame.X;
                if (_CurrentFrame.X >= _SheetSize.X)
                {
                    _CurrentFrame.X = 0;
                    ++_CurrentFrame.Y;
                    if (_CurrentFrame.Y >= _SheetSize.Y)
                    {
                        _CurrentFrame.Y = 0;
                    }
                }
            }
        }

        public virtual void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(_Texture, _Position, new Rectangle((int) (_CurrentFrame.X * _FrameSize.X), (int) (_CurrentFrame.Y * _FrameSize.Y), (int) _FrameSize.X, (int) _FrameSize.Y), Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
        }
    }
}